/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bean.chart;

import com.bean.chart.iterfaces.AbstractChart;
import java.awt.*;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;

/**
 *
 * @author sammael
 */
public class Chart extends AbstractChart implements Serializable {
    
    
    
    private PropertyChangeSupport propertySupport;
    
    
    public Chart() {
        super();
        propertySupport = new PropertyChangeSupport(this);

        this.addChartData("Wykres");
        this.addChartData("Wykres2");
    
        
        this.chartColorMap.put("Wykres", Color.BLUE);
        
        this.chartColorMap.put("Wykres2", Color.RED);
        
        this.addChartDataPoint("Wykres", 16.0);
        this.addChartDataPoint("Wykres", 15.0);
        this.addChartDataPoint("Wykres", 20.0);
        this.addChartDataPoint("Wykres", 30.0);
        this.addChartDataPoint("Wykres", 25.0);
        
        this.addChartDataPoint("Wykres2", 80.0);
        this.addChartDataPoint("Wykres2", 25.0);
        this.addChartDataPoint("Wykres2", 43.0);
        this.addChartDataPoint("Wykres2", 35.23);
        this.addChartDataPoint("Wykres2", 5.15);
        
        
    }
    
    @Override
    public void paintComponent(Graphics g) {
        g.setColor(this.getBackgroundColor());
        g.fillRect(0,0,this.getSize().width,this.getSize().height);
        
        int w = this.getSize().width -2;
        int h = this.getSize().height -2;
        
        Graphics2D g2 = (Graphics2D) g;
        if(this.isGridVisible()){
            paintGrid(g);
        }
        if(this.isValueVisible()){
            paintValue(g, h);
        }
        if(this.isLineVisible()){
            paintLine(g2, w, h);
        }
        if(this.isDotVisible()){
            paintDot(g2, w, h);
        }

        
    }
    
    @Override
    protected void paintGrid(Graphics g) {
       g.setColor(this.getGridColor());
       int w = this.getSize().width -2;
       int h = this.getSize().height -2;
       
       int stepX = w/(this.getValuesCount()-1);
       //step--;
       int margin = (w%this.getValuesCount())/2;
       //margin--;
       int x =0;
       for(int i=0;i<=this.getValuesCount();++i){
           x = (i*stepX)+1;//+margin;
           g.drawLine(x, 1, x, h);
       }
       
       int stepY = h/(getMarksCount());
       int y;
       for(int i = 0 ; i <= getMarksCount();++i){
           y = (i*stepY)+1;
           g.drawLine(1, y, x-1, y);
       }
       
    }

    @Override
    protected void paintLine(Graphics2D g2, int w, int h) {

      Stroke s = new BasicStroke(this.getStrokeSize());
      g2.setStroke(s);
      
      int stepX = w/(this.getValuesCount()-1);
        
         Set set = this.chartMap.entrySet();
      
      Iterator i = set.iterator();
      
      while(i.hasNext()){
          Map.Entry me = (Map.Entry)i.next();
          Color color = this.chartColorMap.get(me.getKey());
          g2.setColor(color);
          int x = 0;
          LinkedList<Double> ls = (LinkedList<Double> ) me.getValue();
          for(int j = 0; j<ls.size(); j++){
              double y = ls.get(j);
              int next = j+1;
              int x1 = x+1;
              if(j == ls.size() - 1){
                  continue;
              }
              else{
              double y1 = ls.get(next);
              double scale = this.getMaxYValue() / y;
              double scale1 = this.getMaxYValue() / y1;
              g2.draw(new Line2D.Double(x*stepX , h - h / scale , x1*stepX, h - h / scale1 ));
              x++;
              }
             
          }
      }
    }

    @Override
    protected void paintDot(Graphics2D g2, int w, int h) {
        
      int size = this.getDotSize();
      
      int stepX = w/(this.getValuesCount()-1);
      
      Set set = this.chartMap.entrySet();
      
      Iterator i = set.iterator();
      
      while(i.hasNext()){
          Map.Entry me = (Map.Entry)i.next();
          Color color = this.chartColorMap.get(me.getKey());
          g2.setColor(color);
          int x = 0;
          LinkedList<Double> ls = (LinkedList<Double> ) me.getValue();
          Iterator j = ls.iterator();
          while(j.hasNext()){
              double y = (Double) j.next();
              double scale = this.getMaxYValue() / y;
              g2.fill(new Rectangle2D.Double(x*stepX - size/2, h - h / scale - size/2, size, size));
              x++;
          }
      }
    }
    @Override
    protected void paintValue(Graphics g, int h){
        g.setColor(this.getValueColor());
        int stepY = h/(getMarksCount());
        double value = this.getMaxYValue() / this.getMarksCount();
        int y;
        for(int i = 0 ; i <= getMarksCount();++i){
            y = (i*stepY)+1;
            double diff = this.getMaxYValue() - i * value;
            DecimalFormat df = new DecimalFormat("#.##");
            String sDiff = df.format(diff);
            if(i == 0);
            else
                g.drawString(sDiff, 5, y-5);
       }
        
    }

    @Override
    protected void propertyChange(String property, double oldval, double newVal) {
        propertySupport.firePropertyChange(property, oldval, newVal);
    }

    @Override
    protected void propertyChange(String property, boolean oldval, boolean newVal) {
        propertySupport.firePropertyChange(property, oldval, newVal);
    }

    @Override
    protected void propertyChange(String property, int oldval, int newVal) {
        propertySupport.firePropertyChange(property, oldval, newVal);
    }

    @Override
    protected void propertyChange(String property, Object oldval, Object newVal) {
        propertySupport.firePropertyChange(property, oldval, newVal);
    }

}
